package com.starview.platform.data;

/**
 * The IArray interface is implemented by array-like objects.
 * 
 * @author fgm
 * 
 */
public interface IArray extends IRelation
{
  /**
   * True if the array has no elements
   * 
   * @return
   */
  @Override
  boolean isEmpty();

  /**
   * See how many elements are in the array
   * 
   * @return the number of elements in the array
   */
  @Override
  int size();

  /**
   * Return the value corresponding to a given index
   * 
   * @param index
   * @return the value at the indicated position. The first offset is 0.
   */
  IValue getCell(int index);

  /**
   * Set the cell at a specific position to a new value. Should NEVER be null.
   * 
   * @param index
   * @param value
   * @throws IndexOutOfBoundsException
   *           when attempting to set a value outside the current bounds of the array.
   */
  void setCell(int index, IValue value);

  /**
   * The substitute function returns a new array value which is equal to the original but with the
   * indicated cell replaced by a new value
   * 
   * This function is guaranteed not to affect the original array
   * 
   * @param index
   *          the index of the cell to replace
   * @param value
   *          the replacement value for the cell
   * @return a new array.
   */
  IArray substituteCell(int index, IValue value);

  /**
   * Splice another list into this one.
   * 
   * @param sub
   *          the list to splice into this list
   * @param index
   *          the index where the first (and subsequent) elements will be spliced in. A value of 0
   *          results in the sub-list being placed in at the start of the list and a value of
   *          {@code size()} results in the sub-list being put at the end of the list.
   * @param to
   *          the index of the first element that forms the remainder of the list
   * @return a new array consisting of the sub array spliced into this array at point index.
   */
  IArray spliceList(IArray sub, int index, int to);

  /**
   * Concatenate a list to the end of the list
   * 
   * @param sub
   *          the list to merge with this list
   * @return
   */
  IArray concatList(IArray sub);

  /**
   * Extract a sub-list from a list.
   * 
   * @param from
   *          the index of the first element to extract
   * @param to
   *          the index of the first element not in the extracted list
   * @return the sub-list. If count is greater than the remaining length of the list then the whole
   *         tail will be returned.
   * @throws IndexOutOfBoundsException
   *           if the start index is not in range.
   */
  IArray slice(int from, int to);

  /**
   * Return a sub-list consisting of all the remaining elements after the front n elements
   * 
   * @param from
   *          the number of elements to 'skip' in creating the sublist.
   * @return a sublist
   * @throws IndexOutOfBoundsException
   */
  IArray slice(int from);

  /**
   * return a new arrya with the elements of this array reversed
   * 
   * @return
   */
  IArray reverse();

  /**
   * Construct a 'shallow' copy of the array.
   * 
   * @throws EvaluationException
   */
  @Override
  IArray shallowCopy();
}
